﻿using CoreHelper;
using Microsoft.AspNetCore.Http;
using Microsoft.Net.Http.Headers;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace CoreWeb
{
    public class ThumbnailOptions
    {
        public string VirtualPath { get; set; }
        public string PhysicalPath { get; set; }
        public int CacheSeconds { get; set; } = 60 * 60 * 24;
    }

    public class ThumbnailMiddleware : IMiddleware
    {
        public ThumbnailOptions Options { get; set; }
        public ThumbnailMiddleware()
        {
            Options = new ThumbnailOptions()
            {
                PhysicalPath = "/upload",
                VirtualPath = "/sf"
            };
        }

        static string GetToken(byte[] buffer)
        {
            MD5 md5 = MD5.Create();
            byte[] checksum = md5.ComputeHash(buffer);
            return Convert.ToBase64String(checksum, 0, checksum.Length);
        }

        public Task InvokeAsync(Microsoft.AspNetCore.Http.HttpContext context, RequestDelegate next)
        {
            if (context.Request.Query.ContainsKey("w") || context.Request.Query.ContainsKey("h"))
            {
                var w = int.Parse(context.Request.Query["w"].FirstOrDefault() ?? "0");
                var h = int.Parse(context.Request.Query["h"].FirstOrDefault() ?? "0");
                var ext = Path.GetExtension(context.Request.Path);

                var filePath = context.Request.Path.Value.Replace(Options.VirtualPath, Options.PhysicalPath);
                var newPath = filePath + "." + w + "_" + h + ext;

                context.Response.ContentType = "image/jpeg";

                //缓存时间

                context.Response.Headers[HeaderNames.CacheControl] = "public,max-age=" + Options.CacheSeconds;

                if (File.Exists(newPath))
                {
                    //缓存时间
                    var buffer = File.ReadAllBytes(newPath);
                    var etag = GetToken(buffer);
                    //context.Response.Headers[HeaderNames.LastModified] = DateTime.Now.ToString("r");
                    var tag = context.Request.Headers[HeaderNames.IfNoneMatch].FirstOrDefault();
                    if (tag != null && tag == etag)
                    {
                        context.Response.StatusCode = StatusCodes.Status304NotModified;
                        return Task.CompletedTask;
                    }
                    else
                    {
                        context.Response.Headers[HeaderNames.ETag] = etag;
                        return context.Response.SendFileAsync(newPath);
                    }
                }
                else
                {
                    if (File.Exists(filePath))
                    {
                        using (var image = Image.FromFile(filePath))
                        {
                            using (var thumb = image.GetThumbnailImage(w, h))
                            {
                                thumb.Save(newPath, ImageFormat.Jpeg);
                            }
                            //缓存时间
                            var buffer = File.ReadAllBytes(newPath);
                            var etag = GetToken(buffer);
                            context.Response.Headers[HeaderNames.ETag] = etag;
                            //context.Response.Headers[HeaderNames.LastModified] = DateTime.Now.ToString("r");
                            return context.Response.SendFileAsync(newPath);
                        }
                    }
                    else
                    {
                        context.Response.StatusCode = 404;
                        return Task.CompletedTask;
                    }
                }
            }
            else
            {
                return next.Invoke(context);
            }
        }
    }
}
